use std::env;
use sqlx::{Pool, Sqlite, SqlitePool};
use time::PrimitiveDateTime;

use crate::api::ApiError;

//建立并返回一个与 SQLite 数据库的连接池
pub async fn establisch_connection() -> Pool<Sqlite> {
    let database_url = env::var("DATABASE_URL").expect("missing DATABASE_URL");
    let pool = SqlitePool::connect(&database_url)
        .await.expect("can't connect to database");
    pool
}


//user表对应的结构体
#[derive(sqlx::FromRow)] //从数据库的行数据（row）中映射并填充其实例字段。
pub struct User {
    pub id: i32,
    pub openid: String,
    pub session_key: String,
    pub created_at: PrimitiveDateTime,
    pub updated_at: PrimitiveDateTime,
}

#[derive(sqlx::FromRow, Debug, serde::Serialize)]
pub struct Counter {
    pub id: i32,
    pub user_id: i32,
    pub name: String,
    pub value: i32,
    pub step: i32,
    pub input_step: bool,
    pub sequence: i32,
    pub created_at: PrimitiveDateTime,
    pub updated_at: PrimitiveDateTime,
}

#[derive(sqlx::FromRow, Debug, serde::Serialize)]
pub struct CounterRecord {
    pub id: i32,
    pub counter_id: i32,
    pub step: i32,
    pub begin: i32,
    pub end: i32,
    pub created_at: PrimitiveDateTime,
    pub updated_at: PrimitiveDateTime,
}


pub async fn get_user_counter(
    id: i32,
    user_id: i32,
    pool: &Pool<Sqlite>,
) -> Result<Counter, ApiError> {

    sqlx::query_as::<_, Counter>(
        "select * from counters where id = ? and user_id = ?",
        )
        .bind(id)
        .bind(user_id)
        .fetch_one(pool)
        .await
        .map_err(|err| match err {
            sqlx::Error::RowNotFound => ApiError::NotFound,
            err => ApiError::from(err),
        })
}